package service

import (
	"boy-go/pkg/auth"
	"boy-go/pkg/config"
	"boy-go/pkg/constants"
	"boy-go/pkg/jwt"
	"boy-go/pkg/redis"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/ua-parser/uap-go/uaparser"
	"time"
)

func NewTokenService() TokenService {
	return &tokenService{}
}

type tokenService struct {
}

func (s *tokenService) GenerateToken(ctx *gin.Context, loginUser auth.LoginUser) string {
	id := uuid.New()
	loginUser.Token = id.String()
	s.setUserAgent(ctx, &loginUser)
	s.refreshToken(ctx, &loginUser)
	return s.createToken(loginUser.Token, loginUser.UserName)
}

func (s *tokenService) setUserAgent(ctx *gin.Context, loginUser *auth.LoginUser) {
	uaString := ctx.GetHeader("User-Agent")
	ip := ctx.ClientIP()
	loginUser.Ipaddr = ip
	loginUser.LoginLocation = ip
	if uaString != "" {
		// 使用 uap-go 解析 User-Agent 字符串
		parser := uaparser.NewFromSaved()
		ua := parser.Parse(uaString)
		loginUser.Browser = ua.UserAgent.Family
		loginUser.Os = ua.Os.Family
	}
}

func (s *tokenService) refreshToken(ctx *gin.Context, loginUser *auth.LoginUser) {
	loginUser.LoginTime = time.Now().Unix()
	expireTime := config.GetTokenConfig().ExpireTime * 60
	loginUser.ExpireTime = loginUser.LoginTime + int64(expireTime)
	userKey := s.getTokenKey(loginUser.Token)
	userJSON, _ := json.Marshal(loginUser)
	redis.SetValueForExpireTime(ctx, userKey, string(userJSON), int64(expireTime))
}
func (s *tokenService) getTokenKey(uuid string) string {
	return constants.LOGIN_TOKEN_KEY + uuid
}
func (s *tokenService) createToken(uuid string, username string) string {
	token, err := jwt.GenerateToken(uuid, username)
	if err != nil {
		panic(err)
	}
	return *token
}
